package jmind.core.http;

import jmind.base.lang.Pair;
import jmind.base.util.DataUtil;
import jmind.base.util.GlobalConstants;
import jmind.base.util.IOUtil;
import jmind.base.util.RequestUtil;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class HttpDefault extends HttpClient {

    @Override
    public String get(String url, String code, int timeout,Map<String, String> headers) {
        long start = System.currentTimeMillis();
        String res = null;
        InputStream in = null;
        try {
            URL uri = new URL(url);
            URLConnection urlConnection = uri.openConnection();
            if (timeout > 0) {
                urlConnection.setReadTimeout(timeout);
            }
            // 设置header
            if (!DataUtil.isEmpty(headers)) {
                for (Map.Entry<String, String> header : headers.entrySet()) {
                    urlConnection.setRequestProperty(header.getKey(), header.getValue());
                }
            }
            in = uri.openStream();
            InputStreamReader isr = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(isr);
            String s = null;
            StringBuilder sb = new StringBuilder();
            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
            res = sb.toString();
            br.close();
            isr.close();
            success(start, url, res);
        } catch (IOException e) {
            fail(start, url, e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
        return res;
    }

    private String post(String url, String body, String code, int timeout) {
        long start = System.currentTimeMillis();
        HttpURLConnection urlConnection = null;
        String res = null;
        try {
            urlConnection = (HttpURLConnection) new URL(url).openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoInput(true);
            urlConnection.setRequestProperty("Accept-Charset", code);
            urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + code);
            if (timeout > 0) {
                urlConnection.setReadTimeout(timeout);
            }

            //   urlConnection.setConnectTimeout(1000);
            if (!DataUtil.isEmpty(body)) {
                urlConnection.setDoOutput(true); // 是否输入参数
                OutputStream outputStream = urlConnection.getOutputStream();
                outputStream.write(body.getBytes(code));
                //  DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
                outputStream.flush();
                outputStream.close();
            }
            InputStream in = urlConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, code));
            StringBuilder builder = new StringBuilder();
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                builder.append(line);
            }
            res = builder.toString();
            success(start, url, res);
        } catch (Exception e) {
            fail(start, url, e);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }

        }
        return res;
    }

    @Override
    public String post(String url, Map<String, ?> params, String code, int timeout) {
        return this.post(url, RequestUtil.toQueryString(params), code, timeout);
    }

    @Override
    public String post(String url, List<Pair<String, String>> params, String code, int timeout) {
        String queryString = null;
        if (!DataUtil.isEmpty(params)) {
            StringBuilder sb = new StringBuilder();
            for (Pair<String, String> pair : params) {
                sb.append("&").append(pair.getFirst()).append("=").append(pair.getSecond());
            }
            queryString = sb.substring(1);
        }
        return this.post(url, queryString, code, timeout);
    }

    // http://314858770.iteye.com/blog/720456
    @Override
    public String postFile(String url, Map<String, ?> params, String fileName, File file, String code) {
        long start = System.currentTimeMillis();
        String boundary = Long.toHexString(start);
        HttpURLConnection conn = null;
        String res = null;
        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");
            conn.setUseCaches(false);
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Charsert", code);
            conn.setRequestProperty("Accept-Charset", code);
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            conn.connect();
            OutputStream outputStream = conn.getOutputStream();
            DataOutputStream ds = new DataOutputStream(outputStream);
            //  参数
            if (!DataUtil.isEmpty(params)) {
                for (Entry<String, ?> entry : params.entrySet()) {
                    ds.writeBytes("--" + boundary + GlobalConstants.CRLF);
                    ds.writeBytes("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"\r\n");
                    ds.writeBytes(GlobalConstants.CRLF);
                    ds.write(entry.getValue().toString().getBytes(code));
                    ds.writeBytes(GlobalConstants.CRLF);
                }
            }

            // upload file
            if (file != null) {
                ds.writeBytes("--" + boundary + GlobalConstants.CRLF);
                ds.writeBytes("Content-Disposition: form-data; name=\"" + fileName + "\"; filename=\"");
                // 中文用对应编码 byte ，没问题
                ds.write(file.getName().getBytes(code));
                ds.writeBytes("\"\r\n");
                ds.writeBytes("Content-Type: " + getContentType(file) + GlobalConstants.CRLF);
                ds.writeBytes(GlobalConstants.CRLF);
                //  这里可以注意一下编码
                ds.write(IOUtil.getBytes(file));
                ds.writeBytes(GlobalConstants.CRLF);
            }
            ds.writeBytes("--" + boundary + "--" + GlobalConstants.CRLF);
            ds.writeBytes(GlobalConstants.CRLF);

            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, code);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
            res = sb.toString();
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            success(start, url, res);
        } catch (Exception e) {
            fail(start, url, e);
        } finally {
            if (conn != null)
                conn.disconnect();

        }
        return res;

    }

    //获取文件的上传类型，图片格式为image/png,image/jpg等。非图片为application/octet-stream  
    private String getContentType(File f) throws Exception {
        ImageInputStream imagein = ImageIO.createImageInputStream(f);
        if (imagein == null) {
            return "application/octet-stream";
        }
        Iterator<ImageReader> it = ImageIO.getImageReaders(imagein);
        if (!it.hasNext()) {
            imagein.close();
            return "application/octet-stream";
        }
        imagein.close();
        return "image/" + it.next().getFormatName().toLowerCase();//将FormatName返回的值转换成小写，默认为大写  

    }

    @Override
    public String postBody(String url, String body, Map<String, String> headers) {
        long start = System.currentTimeMillis();
        HttpURLConnection urlConnection = null;
        String res = null;
        try {
            urlConnection = (HttpURLConnection) new URL(url).openConnection();
            urlConnection.setConnectTimeout(1000);
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            // 设置header
            if (!DataUtil.isEmpty(headers)) {
                for (Map.Entry<String, String> header : headers.entrySet()) {
                    urlConnection.setRequestProperty(header.getKey(), header.getValue());
                }
            }
            urlConnection.getOutputStream().write(body.getBytes(GlobalConstants.UTF8));
            urlConnection.getOutputStream().flush();
            urlConnection.getOutputStream().close();
            InputStream in = urlConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, GlobalConstants.UTF8));
            String line = bufferedReader.readLine();
            StringBuilder builder = new StringBuilder();
            while (line != null) {
                builder.append(line);
                line = bufferedReader.readLine();
            }
            res = builder.toString();
            success(start, url, res);
        } catch (Exception e) {
            fail(start, url, e);
        } finally {
            if (urlConnection != null)
                urlConnection.disconnect();
        }

        return res;
    }

    @Override
    public String postFile(String url, Map<String, ?> params, List<Pair<String, File>> files, String code) {
        // TODO Auto-generated method stub
        return null;
    }

}
